<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>免费域名证书生成</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 text-gray-800 min-h-screen flex flex-col items-center py-10">
<div class="bg-white shadow-lg rounded-2xl w-full max-w-2xl p-8">
    <h1 class="text-2xl font-bold text-center mb-6 text-blue-600">免费域名证书生成</h1>

    <form id="certForm" class="space-y-4">
        <div>
            <label class="block font-semibold mb-1">域名</label>
            <input id="domain" type="text" placeholder="例如 example.com"
                   class="w-full border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring focus:ring-blue-100 focus:border-blue-400" />
        </div>

        <div>
            <label class="block font-semibold mb-1">选择 ACME 证书颁发机构</label>
            <select id="acme" class="w-full border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring focus:ring-blue-100 focus:border-blue-400">
                <option value="LETS_ENCRYPT">Let’s Encrypt（90 天）</option>
                <option value="BUY_PASS_GO_SSL">Buypass Go SSL（180 天）</option>
                <option value="ZERO_SSL">ZeroSSL（90 天）</option>
                <option value="GOOGLE_TRUST" selected>Google Trust（90 天）</option>
            </select>
        </div>

        <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
            <div>
                <label class="block font-semibold mb-1">EAB KID（可选）</label>
                <input id="eabKid" type="text" placeholder="ACME EAB KID（如需）"
                       class="w-full border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring focus:ring-blue-100 focus:border-blue-400" />
            </div>
            <div>
                <label class="block font-semibold mb-1">EAB HMAC Key（可选）</label>
                <input id="eabHmacKey" type="text" placeholder="ACME EAB HMAC Key（如需）"
                       class="w-full border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring focus:ring-blue-100 focus:border-blue-400" />
            </div>
        </div>

        <div class="flex justify-end gap-3">
            <button type="button" id="getDnsBtn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg shadow">
                获取 DNS 验证信息
            </button>
            <button type="button" id="generateBtn" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg shadow">
                生成证书
            </button>
        </div>
    </form>

    <div id="dnsInfo" class="hidden mt-6 bg-blue-50 border border-blue-200 rounded-lg p-4">
        <p class="font-semibold text-blue-700 mb-2">DNS 记录信息：</p>
        <p>记录名：<span id="recordName" class="text-gray-700"></span></p>
        <p>记录值：<span id="recordValue" class="text-gray-700"></span></p>
        <p class="text-sm text-gray-500 mt-2">请在 DNS 服务商处添加此 TXT 记录后再生成证书。</p>
    </div>

    <div id="orders" class="mt-8">
        <div class="flex justify-between items-center mb-2">
            <h2 class="text-lg font-bold text-gray-700 border-b pb-2">历史订单</h2>
            <div class="flex gap-2">
                <button id="exportBtn" class="bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 rounded-lg text-sm shadow">
                    导出
                </button>
                <button id="importBtn" class="bg-gray-500 hover:bg-gray-600 text-white px-3 py-1 rounded-lg text-sm shadow">
                    导入
                </button>
                <input type="file" id="importFile" accept=".json" class="hidden" />
            </div>
        </div>
        <table class="w-full text-sm text-gray-800 border border-gray-200 text-center">
            <thead class="bg-gray-100">
            <tr>
                <th class="p-2 border-b">域名</th>
                <th class="p-2 border-b">ACME</th>
                <th class="p-2 border-b">创建时间</th>
                <th class="p-2 border-b">过期时间</th>
                <th class="p-2 border-b">操作</th>
            </tr>
            </thead>
            <tbody id="orderTableBody"></tbody>
        </table>
    </div>

    <div id="message" class="mt-4 text-center text-sm font-semibold"></div>
</div>

<!-- 详情弹窗 -->
<div id="modal" class="fixed inset-0 bg-black bg-opacity-40 hidden items-center justify-center">
    <div class="bg-white rounded-lg p-6 w-11/12 max-w-2xl shadow-lg">
        <h3 class="font-bold mb-2">订单详情</h3>
        <pre id="modalContent" class="bg-gray-100 p-3 rounded text-xs overflow-auto" style="max-height:40vh"></pre>
        <div class="text-right mt-3">
            <button id="modalClose" class="px-4 py-1 rounded bg-blue-500 text-white">关闭</button>
        </div>
    </div>
</div>

<script>
    const dnsInfo = document.getElementById('dnsInfo');
    const recordNameEl = document.getElementById('recordName');
    const recordValueEl = document.getElementById('recordValue');
    const messageEl = document.getElementById('message');
    const orderTableBody = document.getElementById('orderTableBody');
    const importFile = document.getElementById('importFile');
    const modal = document.getElementById('modal');
    const modalContent = document.getElementById('modalContent');
    const modalClose = document.getElementById('modalClose');

    const ordersKey = 'cert_orders_v4';
    let orders = JSON.parse(localStorage.getItem(ordersKey) || '[]');

    function saveOrders() {
        localStorage.setItem(ordersKey, JSON.stringify(orders));
        renderOrders();
    }

    function renderOrders() {
        orderTableBody.innerHTML = '';
        if (orders.length === 0) {
            orderTableBody.innerHTML = '<tr><td colspan="6" class="text-center text-gray-400 p-3">暂无记录</td></tr>';
            return;
        }
        orders.forEach((o, idx) => {
            const expired = isExpired(o.expireDate);
            const tr = document.createElement('tr');
            tr.className = 'border-b hover:bg-blue-50';
            tr.innerHTML = `
        <td class="p-2">${o.domain}</td>
        <td class="p-2">${o.acme}</td>
        <td class="p-2">${o.createDate}</td>
        <td class="p-2 ${expired ? 'text-red-600 font-semibold' : ''}">${o.expireDate}</td>
        <td class="p-2">
          <a href="${o.downloadUrl || ('/api/certificate/download/' + o.domain)}" class="text-blue-600 hover:underline mr-3" target="_blank">下载</a>
          <button data-idx="${idx}" class="showDetailBtn text-sm text-gray-700 hover:underline mr-2">详情</button>
          <button data-idx="${idx}" class="deleteBtn text-sm text-red-600 hover:underline">删除</button>
        </td>`;
            orderTableBody.appendChild(tr);
        });

        document.querySelectorAll('.deleteBtn').forEach(btn => {
            btn.onclick = e => {
                const i = Number(e.target.dataset.idx);
                if (confirm('确认删除这条订单？')) {
                    orders.splice(i, 1);
                    saveOrders();
                }
            };
        });
        document.querySelectorAll('.showDetailBtn').forEach(btn => {
            btn.onclick = e => {
                const i = Number(e.target.dataset.idx);
                modalContent.textContent = JSON.stringify(orders[i], null, 2);
                modal.classList.remove('hidden');
                modal.style.display = 'flex';
            };
        });
    }

    function isExpired(dateStr) {
        return new Date(dateStr + 'T23:59:59') < new Date();
    }

    renderOrders();

    document.getElementById('getDnsBtn').addEventListener('click', async () => {
        const domain = document.getElementById('domain').value.trim();
        const acme = document.getElementById('acme').value;
        const eabKid = document.getElementById('eabKid').value.trim();
        const eabHmacKey = document.getElementById('eabHmacKey').value.trim();

        if (!domain) return alert('请输入域名');

        messageEl.textContent = '正在获取 DNS 验证信息...';
        try {
            const payload = { domain, acme, eabKid, eabHmacKey };
            const res = await fetch('/api/certificate/dns-challenge', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });
            const data = await res.json();
            if (data.success) {
                dnsInfo.classList.remove('hidden');
                recordNameEl.textContent = data.recordName;
                recordValueEl.textContent = data.recordValue;
                messageEl.textContent = 'DNS 验证信息已获取，请添加 TXT 记录后再生成证书。';
                localStorage.setItem('current_order', JSON.stringify({
                    domain, acme, eabKid, eabHmacKey
                }));
            } else {
                messageEl.textContent = '获取失败：' + (data.message || '未知错误');
            }
        } catch (err) {
            messageEl.textContent = '请求出错：' + err.message;
        }
    });

    document.getElementById('generateBtn').addEventListener('click', async () => {
        const current = JSON.parse(localStorage.getItem('current_order') || 'null');
        if (!current) return alert('请先获取 DNS 验证信息');

        messageEl.textContent = '正在生成证书，请稍候...';
        try {
            const res = await fetch('/api/certificate/generate', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(current)
            });
            const data = await res.json();
            if (data.success) {
                messageEl.textContent = '证书生成成功，可下载。';
                const now = new Date();
                const expire = new Date(now);
                expire.setDate(expire.getDate() + (current.acme === 'BUY_PASS_GO_SSL' ? 180 : 90));
                const order = {
                    domain: current.domain,
                    acme: current.acme,
                    createDate: now.toISOString().split('T')[0],
                    expireDate: expire.toISOString().split('T')[0],
                    eabKid: current.eabKid || '',
                    eabHmacKey: current.eabHmacKey || '',
                    downloadUrl: data.downloadUrl || ('/api/certificate/download/' + current.domain)
                };
                orders = orders.filter(o => o.domain !== current.domain); // 覆盖旧域名记录
                orders.push(order);
                saveOrders();
                localStorage.removeItem('current_order');
            } else {
                messageEl.textContent = '生成失败：' + (data.message || '未知错误');
            }
        } catch (err) {
            messageEl.textContent = '请求出错：' + err.message;
        }
    });

    // 导出
    document.getElementById('exportBtn').addEventListener('click', () => {
        if (orders.length === 0) return alert('没有可导出的订单');
        const blob = new Blob([JSON.stringify(orders, null, 2)], { type: 'application/json' });
        const a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = `cert_orders_${new Date().toISOString().split('T')[0]}.json`;
        a.click();
    });

    // 导入
    document.getElementById('importBtn').addEventListener('click', () => importFile.click());
    importFile.addEventListener('change', e => {
        const file = e.target.files[0];
        if (!file) return;
        const reader = new FileReader();
        reader.onload = ev => {
            try {
                const imported = JSON.parse(ev.target.result);
                if (!Array.isArray(imported)) throw new Error('文件不是订单数组');
                for (const it of imported) {
                    if (!it.domain || !it.createDate || !it.expireDate) throw new Error('订单缺少必要字段');
                }
                orders = imported;
                saveOrders();
                messageEl.textContent = '导入成功';
            } catch (err) {
                alert('导入失败：' + err.message);
            }
        };
        reader.readAsText(file);
    });

    modalClose.addEventListener('click', () => {
        modal.classList.add('hidden');
        modal.style.display = 'none';
    });
</script>
</body>
</html>
